package com.fy.fyai.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fy.fyai.common.config.AiModelManager;
import com.fy.fyai.common.constant.PromptConstant;
import com.fy.fyai.common.enums.AiChatConversationStatusEnum;
import com.fy.fyai.common.enums.AiModelEnum;
import com.fy.fyai.common.ex.handler.ExHandler;
import com.fy.fyai.common.result.R;
import com.fy.fyai.common.utils.AITitleCleaner;
import com.fy.fyai.common.utils.LoginUser;
import com.fy.fyai.common.utils.SnowflakeIdGenerator;
import com.fy.fyai.mapper.AiChatConversationMapper;
import com.fy.fyai.model.entity.AiChatConversation;
import com.fy.fyai.model.entity.MessageContent;
import com.fy.fyai.model.vo.LoginUserSession;
import com.fy.fyai.service.AiChatConversationService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.messages.Message;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

import static com.fy.fyai.common.result.R.ok;

/**
 * AI聊天会话Service实现类
 *
 * @author fwq
 * @date 2025-10-24
 */
@Slf4j
@Service
public class AiChatConversationServiceImpl extends ServiceImpl<AiChatConversationMapper, AiChatConversation> implements AiChatConversationService {

    @Resource
    private AiModelManager aiModelManager;

    @Resource
    private AiChatConversationMapper aiChatConversationMapper;

    /**
     * 创建新会话
     * @return 新会话
     */
    @Override
    @Transactional
    public AiChatConversation createNewConversation(Integer userId) {


        // 创建第一条消息
        MessageContent messageContent = MessageContent.builder()
                .role("assistant")
                .content("你好!请问有什么我可以帮助你的吗?")
                .send_time(LocalDateTime.now().toString())
                .tokens(new Random().nextInt(100))
                .build();

        // 1. 创建新会话（不包含消息内容）
        AiChatConversation aiChatConversation = AiChatConversation.builder()
                .conversationName("新会话")
                .userId(userId)
                .messageCount(1)
                .conversationId(SnowflakeIdGenerator.generateId())
                .status(AiChatConversationStatusEnum.ACTIVE.getCode()) // 活跃状态
                .createTime(new Date())
                .updateTime(new Date())
                .lastMessageTime(new Date())
                .messageContent("[]") // 初始化为空数组
                .build();

        // 2. 保存到数据库
        save(aiChatConversation);

        // 3. 使用JSONB操作设置第一条消息（包装成数组）
        String firstMessageArrayJson = "[" + JSONUtil.toJsonStr(messageContent) + "]";

        LambdaUpdateWrapper<AiChatConversation> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AiChatConversation::getId, aiChatConversation.getId())
                .setSql("last_message_time = NOW()")
                .setSql("update_time = NOW()")
                .setSql("message_content = {0} ::jsonb", firstMessageArrayJson);

        update(updateWrapper);
        return aiChatConversation;
    }

    /**
     * 向会话添加新消息
     *
     * @param conversationId 会话ID
     * @param messages       新消息
     * @return 是否成功
     */
    @Override
    @Transactional
    public void addMessageToConversation(String conversationId, List<Message> messages) {
        Message message = messages.get(0);

        String messageText = message.getText();
        // 创建新消息
        MessageContent messageContent = MessageContent.builder()
                .role(message.getMessageType().getValue())
                .content(messageText)
                .send_time(LocalDateTime.now().toString())
                .tokens(new Random().nextInt(100))
                .attachments(List.of()) // 后续可能会扩展文件上传提问功能，那个时候使用
                .build();

        // 按conversationId查询会话（异步流中无法获取用户信息，不做用户校验）
        AiChatConversation aiChatConversation = getOne(new LambdaQueryWrapper<AiChatConversation>()
                .eq(AiChatConversation::getConversationId, conversationId)
                .ne(AiChatConversation::getStatus, AiChatConversationStatusEnum.LOGICAL_DELETED.getCode()));

        // 会话不存在则记录错误返回（异步流中无法创建，需要在前端提前创建）
        if (aiChatConversation == null) {
            log.error("会话不存在: conversationId={}", conversationId);
            return;
        }

        int messageCount = aiChatConversation.getMessageCount();
        if (messageCount <= 1) {
            // 使用常量中的提示词生成标题
            String prompt = PromptConstant.TITLE_GENERATION_PROMPT + messageText;

            // 调用AI模型生成标题（使用默认模型）
            String rawTitle = aiModelManager.call(AiModelEnum.GEMMA_2B.getModelName(), prompt);

            // 使用工具类清理标题（自动去除思考过程并限制长度）
            String title = AITitleCleaner.removeFirstThinkTag(rawTitle);

            // 如果清理后的标题超过128字符，截取前128字符
            if (title.length() > 128) title = title.substring(0, 128);

            aiChatConversation.setConversationName(title);
        }
        aiChatConversation.setMessageCount(messageCount + 1);

        // 只对用户消息进行摘要，AI消息不需要摘要
        String prompt = PromptConstant.CONTENT_SUMMARY_PROMPT + messageText;
        String rawSummary = aiModelManager.call(AiModelEnum.GEMMA_2B.getModelName(), prompt);
        String summary = AITitleCleaner.removeFirstThinkTag(rawSummary);
        messageContent.setContent_summary(summary);

        // 1. 将消息对象转换为JSON字符串并包装成数组格式
        String messageJson = JSONUtil.toJsonStr(messageContent);
        // 确保是数组格式（用[]包裹）
        String messageArrayJson = "[" + messageJson + "]";

        // 2. 使用PostgreSQL JSONB操作直接追加消息（传入数组格式）

        // 方式1：使用LambdaUpdateWrapper更新（推荐）
        LambdaUpdateWrapper<AiChatConversation> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(AiChatConversation::getConversationId, conversationId)
                .setSql("message_content = message_content || {0}::jsonb", messageArrayJson)
                .setSql("last_message_time = NOW()")
                .setSql("update_time = NOW()");
        update(updateWrapper);

        // 方式2：使用注解方法（已注释，保留备用）
        // aiChatSessionMapper.appendMessage(sessionId, messageArrayJson);

        // 3. 更新会话信息（不包括messageContent，避免触发触发器问题）
        // 注意：不更新messageContent字段，只更新sessionName和messageCount
        AiChatConversation updateConversation = new AiChatConversation();
        updateConversation.setConversationId(conversationId);
        updateConversation.setId(aiChatConversation.getId());
        updateConversation.setConversationName(aiChatConversation.getConversationName());
        updateConversation.setMessageCount(aiChatConversation.getMessageCount());
        updateById(updateConversation);
    }

    /**
     * 获取会话的所有消息
     *
     * @param conversationId 会话ID
     * @return 会话消息列表
     */
    @Override
    public R getConversationMessages(String conversationId) {
        AiChatConversation aiChatConversation = this.getOne(new LambdaQueryWrapper<AiChatConversation>().eq(AiChatConversation::getConversationId, conversationId));

        ExHandler.throwIf(aiChatConversation == null, "会话不存在");
        List<MessageContent> messageContentList = JSONUtil.toList(aiChatConversation.getMessageContent(), MessageContent.class);

        Map<String, Object> result = new HashMap<>();
        result.put("conversationName", aiChatConversation.getConversationName());
        result.put("messageCount", aiChatConversation.getMessageCount());
        result.put("lastMessageTime", aiChatConversation.getLastMessageTime());
        result.put("createTime", aiChatConversation.getCreateTime());
        result.put("userId", aiChatConversation.getUserId());
        result.put("sessionId", aiChatConversation.getConversationId());
        result.put("messageContentList", messageContentList);
        return ok(result);
    }

    /**
     * 获取指定会话的最近K条消息
     *
     * @param conversationId 会话ID
     * @param lastN          最近K条
     * @return 消息列表
     */
    @Override
    public List<MessageContent> getTopKChatMemory(String conversationId, int lastN) {
        // 直接调用底层注解SQL（数据库侧已排序截断）
        List<String> msgJsonList = aiChatConversationMapper.selectTopKMessageJson(conversationId, lastN);
        if (msgJsonList == null || msgJsonList.isEmpty()) return new ArrayList<>();
        // 反序列化List<MessageContent>（msgJsonList顺序为数据库倒序，reverse以升序返回）
        List<MessageContent> msgs = msgJsonList.stream()
                .map(json -> JSONUtil.toBean(json, MessageContent.class))
                .toList();

        // 修复：创建可变列表副本后再执行reverse操作
        List<MessageContent> mutableMsgs = new ArrayList<>(msgs);
        Collections.reverse(mutableMsgs);
        return mutableMsgs;
    }

     /**
      * 清空指定会话的聊天记忆
      * @param conversationId 会话ID
      */
    @Override
    @Transactional
    public void clearChatMemory(String conversationId) {
        AiChatConversation aiChatConversation = getOne(new LambdaQueryWrapper<AiChatConversation>()
                .eq(AiChatConversation::getConversationId, conversationId)
                .eq(AiChatConversation::getUserId, LoginUser.getLoginUserId())
                .ne(AiChatConversation::getStatus, AiChatConversationStatusEnum.LOGICAL_DELETED.getCode()));

        if (aiChatConversation == null) return;

        aiChatConversation.setMessageContent("[]");
        aiChatConversation.setMessageCount(0);
        aiChatConversation.setLastMessageTime(null);
        aiChatConversation.setUpdateTime(new Date());
        updateById(aiChatConversation);
    }
}
